#include <omp.h> 
#include <stdio.h>
static long num_steps = 100000; 
#define PAD 8 // assume 64 byte L1 cache line size 
double step; 
#define NUM_THREADS 4 

void main () {
    double x, pi, sum[NUM_THREADS][PAD]; 
    step = 1.0/(double) num_steps; 
    omp_set_num_threads(NUM_THREADS) ;
    #pragma omp parallel 
    {
        double x; 
        int id = omp_get_thread_num(); 
        sum[id][0]=0.0;
        for (int i=id; i< num_steps; i=i+NUM_THREADS){ 
            x = (i-0.5)*step; 
            sum[id][0] += 4.0/(1.0+x*x);
        } 
    }
    for(int i=0;i<NUM_THREADS;i++) pi += sum[i][0] * step;
    printf("pi = %.20lf\n", pi);
}
